package de.koller.oceanFramework.gl.util;

import de.koller.oceanFramework.tree.Sea3X;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;

/**
 * 
 * @author Fabian Koller
 */
public class InputGL extends Sea3X {

	private final Set<Integer> keyPressed = new HashSet<>();
	private final Set<Integer> keyReleased = new HashSet<>();
	private final Set<Integer> mousePressed = new HashSet<>();
	private final Set<Integer> mouseReleased = new HashSet<>();
	private final List<Character> charactersPressed = new ArrayList<>();
	private int mouseWheel = 0;
	
	private int height;

	/**
	 * 
	 */
	@Override
	protected void init() {
		super.init();
		
		this.height = Display.getDisplayMode().getHeight();
	}
	
	
	
	/**
	 * 
	 * @param elapsedTime
	 */
	@Override
	protected void update( int elapsedTime ) {
		super.update( elapsedTime );
		
		keyPressed.clear();
		keyReleased.clear();
		charactersPressed.clear();
		mousePressed.clear();
		mouseReleased.clear();
		mouseWheel = 0;
		
		while( Keyboard.next() ) {
			int k = Keyboard.getEventKey();
			if( Keyboard.getEventKeyState() ) {
				keyPressed.add( k );
				charactersPressed.add( Keyboard.getEventCharacter() );
			} else {
				keyReleased.add( k );
			}
		}
		
		while( Mouse.next() ) {
			int k = Mouse.getEventButton();
			if( Mouse.getEventButtonState() )
				mousePressed.add( k );
			else
				mouseReleased.add( k );
			mouseWheel += Mouse.getEventDWheel();
		}
		
	}

	public int getDMouseWheel() {
		return mouseWheel;
	}
	
	/**
	 * 
	 * @param key
	 * @return
	 */
	public boolean isKeyPressed( int key ) {
		return keyPressed.contains( key );
	}
	
	/**
	 * 
	 * @param key
	 * @return
	 */
	public boolean isKeyReleased( int key ) {
		return keyReleased.contains( key );
	}
	
	/**
	 * 
	 * @param button
	 * @return
	 */
	public boolean isMousePressed( int button ) {
		return mousePressed.contains( button );
	}
	
	/**
	 * 
	 * @param button
	 * @return
	 */
	public boolean isMouseReleased( int button ) {
		return mouseReleased.contains( button );
	}
	
	/**
	 * 
	 * @return
	 */
	public int getMouseX() {
		return Mouse.getX();
	}
	
	/**
	 * 
	 * @return
	 */
	public int getMouseY() {
		return height - Mouse.getY();
	}
	
	public int getMouseDX() {
		return Mouse.getDX();
	}
	
	public int getMouseDY() {
		return Mouse.getDY() * -1;
	}
	
	public void grabMouse() {
		Mouse.setGrabbed( true );
	}
	
	public void unGrabMouse() {
		Mouse.setGrabbed( false );
	}
	
	/**
	 * 
	 * @return
	 */
	public float getMouseScaledX() {
		return Mouse.getX() / 64f;
	}
	
	/**
	 * 
	 * @return
	 */
	public float getMouseScaledY() {
		return (height - Mouse.getY()) / 64f;
	}
	
	/**
	 * 
	 * @param mouseButton
	 * @return
	 */
	public boolean isMouseDown( int mouseButton ) {
		return Mouse.isButtonDown( mouseButton );
	}
	
	/**
	 * 
	 * @param key
	 * @return
	 */
	public boolean isKeyDown( int key ) {
		return Keyboard.isKeyDown( key );
	}

	public Set<Integer> getPressedKeys() {
		return keyPressed;
	}

	public List<Character> getCharactersPressed() {
		return charactersPressed;
	}

}
